package top.hmtools.makedata.random.englishName;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class EnglishNameGenerator {

	private static WordLawConfig wordLawConfig;
	
	static {
		wordLawConfig = new WordLawConfig();
	}
	
	/**
	 * 随机生成英文名字
	 * <br>FIXME 经测试，当 wordLength >= 9时，会出现无法生成的异常，待处理。
	 * @param startWith
	 * @param wordLength
	 * @return
	 */
	public static String generate(String startWith,int wordLength){
		return recursive(startWith, wordLength);
	}
	
	
	private static String recursive(String startWith,int wordLength){
		if(startWith == null){
			startWith = "";
		}
		if(wordLength < 1){
			wordLength = 6;
		}
		
		//如果要生成的英文名称单词长度小于等于指定的前缀，则直接返回前缀
		if(startWith.length()>=wordLength){
			return startWith;
		}
		
		List<String> alphaSet = new ArrayList<>( Arrays.asList( "abcdefghijklmnopqrstuvwxyz".split("") ) );
		while(alphaSet.size()>0){
			int randomii = EnglishNameGenerator.random(0, alphaSet.size()-1);
			String alpha = alphaSet.get(randomii);
			final String k1 = startWith != null && startWith.length()>0?startWith.charAt(startWith.length()-1)+"":null;
			
			//设置单词组合字母出现概率法则条件
			boolean markovA = wordLawConfig.markov(k1, alpha) / wordLawConfig.maxMarkovComb() > 0.2;
			boolean markovB = wordLawConfig.markov(k1, alpha) / wordLawConfig.dixLen() > 0.06;
			boolean position = wordLawConfig.position(alpha, startWith.length()+"") / wordLawConfig.alphaFrequency(alpha) > 0.05;
			
			if(startWith.length() == 0 ||
					(markovA || markovB) &&
					position
					){
				String newWordTmp = EnglishNameGenerator.recursive(startWith+alpha, wordLength);
				if(newWordTmp == null || newWordTmp.length() == wordLength){
					return newWordTmp;
				}
			}
			alphaSet.remove( alpha );
		}
		return startWith;
	}
	
	/**
	 * 生成指定范围内的随机整数
	 * @param minInclusive
	 * @param maxInclusive
	 * @return
	 */
	private static int random( int minInclusive, int maxInclusive ){
        return minInclusive + (int)( Math.random() * ( maxInclusive - minInclusive ) );
    }
	
}
